# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# GNU Makefile based on shared rules provided by the Native Client SDK.
# See README.Makefiles for more details.

CFLAGS :=-g -O0 -pthread -D__ANDROID__ -DANDROID -DBIONIC -fPIC -Wno-incompatible-library-redeclaration

LIBC_CFLAGS += -I$(SRC_ROOT)/stdlib -I$(SRC_ROOT)string -I$(SRC_ROOT)/stdio
LIBC_CFLAGS += -I$(SRC_ROOT)/private -I$(SRC_ROOT) -I$(SRC_ROOT)/arch-nacl/syscalls
LIBC_CFLAGS += -I$(SRC_ROOT)/upstream-netbsd

LIBC_CFLAGS +=-MD -DNACL_SDK_DEBUG -include AndroidConfig.h -Wstrict-aliasing=2 
LIBC_CFLAGS +=-U_FORTIFY_SOURCE -DANDROID_CHANGES -fno-short-enums -funwind-tables -fno-stack-protector -fno-strict-aliasing
LIBC_CFLAGS +=-fno-exceptions -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables
LIBC_CFLAGS +=-DINET6 -DUSG_COMPAT -DANDROID_SMP=1 -D_GNU_SOURCE -DHAVE_MORECORE=0 -D_USE_NACL_SYS_ALIAS_=1 -fPIC

ARM_FLAGS :=-mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon
ARM_FLAGS +=-DTM_GMTOFF=tm_gmtoff -DUSG_COMPAT=1 -DHAVE_ARM_TLS_REGISTER
ARM_FLAGS +=-gdwarf-3

X86_FLAGS :=-DUSES_SSE2 -DFLOATING_POINT -D_BYTE_ORDER=_LITTLE_ENDIAN

ifeq ($(GCC_ARCH),arm)
ARCH_FLAGS:=$(ARM_FLAGS)
else
ARCH_FLAGS:=$(X86_FLAGS)
endif

$(eval $(call BASIC_COMPILE_TARGET,$(INS_ROOT)/crtbegin.o,$(SRC_ROOT)/arch-nacl/bionic/crtbegin.c,$(CC),$(ARCH_FLAGS) $(CFLAGS) -DCRT_DYNAMIC))
$(eval $(call BASIC_COMPILE_TARGET,$(INS_ROOT)/crtbeginS.o,$(SRC_ROOT)/arch-nacl/bionic/crtbegin.c,$(CC),$(ARCH_FLAGS) $(CFLAGS) -DCRT_SO))
$(eval $(call BASIC_COMPILE_TARGET,$(INS_ROOT)/crtbeginT.o,$(SRC_ROOT)/arch-nacl/bionic/crtbegin.c,$(CC),$(ARCH_FLAGS) $(CFLAGS) -DCRT_STATIC))
$(eval $(call BASIC_COMPILE_TARGET,$(INS_ROOT)/crtend.o,$(SRC_ROOT)/arch-nacl/bionic/crtend.c,$(CC),$(ARCH_FLAGS) $(CFLAGS) -DCRT_STATIC))
$(eval $(call BASIC_COMPILE_TARGET,$(INS_ROOT)/crtendS.o,$(SRC_ROOT)/arch-nacl/bionic/crtend.c,$(CC),$(ARCH_FLAGS) $(CFLAGS) -DCRT_SO))

C_UNISTD_SOURCES = \
  unistd/abort.c \
  unistd/alarm.c \
  unistd/brk.c \
  unistd/daemon.c \
  unistd/eventfd.c \
  unistd/exec.c \
  unistd/fcntl.c \
  unistd/fnmatch.c \
  unistd/fstatfs.c \
  unistd/ftime.c \
  unistd/ftok.c \
  unistd/getdtablesize.c \
  unistd/gethostname.c \
  unistd/getopt_long.c \
  unistd/getpgrp.c \
  unistd/getpriority.c \
  unistd/getpt.c \
  unistd/initgroups.c \
  unistd/isatty.c \
  unistd/issetugid.c \
  unistd/killpg.c \
  unistd/openat.c \
  unistd/opendir.c \
  unistd/pathconf.c \
  unistd/perror.c \
  unistd/popen.c \
  unistd/pread.c \
  unistd/pselect.c \
  unistd/ptsname.c \
  unistd/ptsname_r.c \
  unistd/pwrite.c \
  unistd/raise.c \
  unistd/reboot.c \
  unistd/recv.c \
  unistd/sbrk.c \
  unistd/send.c \
  unistd/setegid.c \
  unistd/setuid.c \
  unistd/seteuid.c \
  unistd/setreuid.c \
  unistd/setresuid.c \
  unistd/setpgrp.c \
  unistd/sigblock.c \
  unistd/siginterrupt.c \
  unistd/siglist.c \
  unistd/signal.c \
  unistd/signame.c \
  unistd/sigsetmask.c \
  unistd/sigsuspend.c \
  unistd/sigwait.c \
  unistd/sleep.c \
  unistd/statfs.c \
  unistd/swab.c \
  unistd/sysconf.c \
  unistd/syslog.c \
  unistd/system.c \
  unistd/tcgetpgrp.c \
  unistd/tcsetpgrp.c \
  unistd/time.c \
  unistd/umount.c \
  unistd/unlockpt.c \
  unistd/usleep.c \
  unistd/wait.c
#  unistd/open.c \

C_STDIO_SOURCES = \
  stdio/asprintf.c \
  stdio/clrerr.c \
  stdio/fclose.c \
  stdio/fdopen.c \
  stdio/feof.c \
  stdio/ferror.c \
  stdio/fflush.c \
  stdio/fgetc.c \
  stdio/fgetln.c \
  stdio/fgetpos.c \
  stdio/fgets.c \
  stdio/fileno.c \
  stdio/findfp.c \
  stdio/flags.c \
  stdio/flockfile.c \
  stdio/fopen.c \
  stdio/fprintf.c \
  stdio/fpurge.c \
  stdio/fputc.c \
  stdio/fputs.c \
  stdio/fread.c \
  stdio/freopen.c \
  stdio/fscanf.c \
  stdio/fseek.c \
  stdio/fsetpos.c \
  stdio/ftell.c \
  stdio/funopen.c \
  stdio/fvwrite.c \
  stdio/fwalk.c \
  stdio/fwrite.c \
  stdio/getc.c \
  stdio/getchar.c \
  stdio/gets.c \
  stdio/makebuf.c \
  stdio/mktemp.c \
  stdio/printf.c \
  stdio/putc.c \
  stdio/putchar.c \
  stdio/puts.c \
  stdio/putw.c \
  stdio/refill.c \
  stdio/remove.c \
  stdio/rewind.c \
  stdio/rget.c \
  stdio/scanf.c \
  stdio/setbuf.c \
  stdio/setbuffer.c \
  stdio/setvbuf.c \
  stdio/snprintf.c \
  stdio/sprintf.c \
  stdio/sscanf.c \
  stdio/stdio.c \
  stdio/tempnam.c \
  stdio/tmpfile.c \
  stdio/tmpnam.c \
  stdio/ungetc.c \
  stdio/vasprintf.c \
  stdio/vfprintf.c \
  stdio/vfscanf.c \
  stdio/vprintf.c \
  stdio/vsnprintf.c \
  stdio/vsprintf.c \
  stdio/vscanf.c \
  stdio/vsscanf.c \
  stdio/wbuf.c \
  stdio/wsetup.c \
  stdio/__fgets_chk.c \
  stdio/__snprintf_chk.c \
  stdio/__sprintf_chk.c \
  stdio/__vsnprintf_chk.c \
  stdio/__vsprintf_chk.c \

C_STDLIB_SOURCES = \
  stdlib/_rand48.c \
  stdlib/assert.c \
  stdlib/atexit.c \
  stdlib/atoi.c \
  stdlib/atol.c \
  stdlib/atoll.c \
  stdlib/bsearch.c \
  stdlib/ctype_.c \
  stdlib/div.c \
  stdlib/exit.c \
  stdlib/getenv.c \
  stdlib/jrand48.c \
  stdlib/ldiv.c \
  stdlib/lldiv.c \
  stdlib/locale.c \
  stdlib/lrand48.c \
  stdlib/mrand48.c \
  stdlib/nrand48.c \
  stdlib/putenv.c \
  stdlib/qsort.c \
  stdlib/seed48.c \
  stdlib/setenv.c \
  stdlib/setjmperr.c \
  stdlib/srand48.c \
  stdlib/strntoimax.c \
  stdlib/strntoumax.c \
  stdlib/strtod.c \
  stdlib/strtoimax.c \
  stdlib/strtol.c \
  stdlib/strtoll.c \
  stdlib/strtoul.c \
  stdlib/strtoull.c \
  stdlib/strtoumax.c \
  stdlib/tolower_.c \
  stdlib/toupper_.c \
  stdlib/wchar.c \
  bionic/dlmalloc.c
#//  bionic/malloc_debug_common.cpp

C_STRING_SOURCES = \
  string/bcopy.c \
  string/bzero.c \
  string/index.c \
  string/memccpy.c \
  string/memchr.c \
  string/memcmp.c \
  string/memcpy.c \
  string/memmove.c \
  string/memmem.c \
  string/memrchr.c \
  string/memset.c \
  string/memswap.c \
  string/strcasecmp.c \
  string/strcasestr.c \
  string/strcat.c \
  string/strchr.c \
  string/strcoll.c \
  string/strcpy.c \
  string/strcspn.c \
  string/strdup.c \
  string/strlcat.c \
  string/strlcpy.c \
  string/strncat.c \
  string/strncmp.c \
  string/strncpy.c \
  string/strndup.c \
  string/strnlen.c \
  string/strpbrk.c \
  string/strrchr.c \
  string/strsep.c \
  string/strspn.c \
  string/strstr.c \
  string/strtok.c \
  string/strtotimeval.c \
  string/strcmp.c \
  string/strlen.c \
  string/__memcpy_chk.c \
  string/__memmove_chk.c \
  string/__memset_chk.c \
  string/__strcat_chk.c \
  string/__strcpy_chk.c \
  string/__strlcat_chk.c \
  string/__strlcpy_chk.c \
  string/__strlen_chk.c \
  string/__strncat_chk.c \
  string/__strncpy_chk.c \
  wchar/wcpcpy.c \
  wchar/wcpncpy.c \
  wchar/wcscasecmp.c \
  wchar/wcscat.c \
  wchar/wcschr.c \
  wchar/wcscmp.c \
  wchar/wcscoll.c \
  wchar/wcscpy.c \
  wchar/wcscspn.c \
  wchar/wcsdup.c \
  wchar/wcslcat.c \
  wchar/wcslcpy.c \
  wchar/wcslen.c \
  wchar/wcsncasecmp.c \
  wchar/wcsncat.c \
  wchar/wcsncmp.c \
  wchar/wcsncpy.c \
  wchar/wcsnlen.c \
  wchar/wcspbrk.c \
  wchar/wcsrchr.c \
  wchar/wcsspn.c \
  wchar/wcsstr.c \
  wchar/wcstok.c \
  wchar/wcswidth.c \
  wchar/wcsxfrm.c \
  wchar/wmemchr.c \
  wchar/wmemcmp.c \
  wchar/wmemcpy.c \
  wchar/wmemmove.c \
  wchar/wmemset.c

C_MISC_SOURCES = \
  inet/bindresvport.c \
  inet/inet_addr.c \
  inet/inet_aton.c \
  inet/inet_ntoa.c \
  inet/inet_ntop.c \
  inet/inet_pton.c \
  inet/ether_aton.c \
  inet/ether_ntoa.c \
  tzcode/asctime.c \
  tzcode/difftime.c \
  tzcode/localtime.c \
  tzcode/strftime.c \
  tzcode/strptime.c \
  bionic/__set_errno.c \
  bionic/bionic_clone.c \
  bionic/cpuacct.c \
  bionic/arc4random.c \
  bionic/basename.c \
  bionic/basename_r.c \
  bionic/clearenv.c \
  bionic/dirname.c \
  bionic/dirname_r.c \
  bionic/drand48.c \
  bionic/erand48.c \
  bionic/err.c \
  bionic/fdprintf.c \
  bionic/fts.c \
  bionic/getcwd.c \
  bionic/if_nametoindex.c \
  bionic/if_indextoname.c \
  bionic/ioctl.c \
  bionic/ldexp.c \
  bionic/libc_init_common.c \
  bionic/logd_write.c \
  bionic/memmove_words.c \
  bionic/pututline.c \
  bionic/realpath.c \
  bionic/sched_getaffinity.c \
  bionic/sched_getcpu.c \
  bionic/sched_cpualloc.c \
  bionic/sched_cpucount.c \
  bionic/semaphore.c \
  bionic/strerror.c \
  bionic/strerror_r.c \
  bionic/strsignal.c \
  bionic/system_properties.c \
  bionic/tdestroy.c \
  bionic/time64.c \
  bionic/thread_atexit.c \
  bionic/utime.c \
  bionic/utmp.c \
  bionic/__errno.c \
  bionic/pthread.c \
  bionic/pthread-atfork.c \
  bionic/pthread-rwlocks.c \
  bionic/pthread-timers.c \
  bionic/ptrace.c
#  bionic/pthread_debug.c \

C_NACL_SOURCES = \
  arch-nacl/bionic/nacl_read_tp.c \
  arch-nacl/bionic/__get_sp.c \
  arch-nacl/bionic/__set_tls.c \
  arch-nacl/bionic/atexit.c \
  arch-nacl/bionic/clone.c \
  arch-nacl/syscalls/accept.c \
  arch-nacl/syscalls/access.c \
  arch-nacl/syscalls/bind.c \
  arch-nacl/syscalls/chdir.c \
  arch-nacl/syscalls/chmod.c \
  arch-nacl/syscalls/chown.c \
  arch-nacl/syscalls/clock_getres.c \
  arch-nacl/syscalls/clock_gettime.c \
  arch-nacl/syscalls/close.c \
  arch-nacl/syscalls/connect.c \
  arch-nacl/syscalls/dup.c \
  arch-nacl/syscalls/dup2.c \
  arch-nacl/syscalls/enosys.c \
  arch-nacl/syscalls/_exit.c \
  arch-nacl/syscalls/_exit_thread.c \
  arch-nacl/syscalls/fchdir.c \
  arch-nacl/syscalls/fchmod.c \
  arch-nacl/syscalls/fchown.c \
  arch-nacl/syscalls/fdatasync.c \
  arch-nacl/syscalls/fstat.c \
  arch-nacl/syscalls/fsync.c \
  arch-nacl/syscalls/futex.c \
  arch-nacl/syscalls/__getcwd.c \
  arch-nacl/syscalls/getdents.c \
  arch-nacl/syscalls/getpeername.c \
  arch-nacl/syscalls/getpid.c \
  arch-nacl/syscalls/getsockname.c \
  arch-nacl/syscalls/getsockopt.c \
  arch-nacl/syscalls/gettid.c \
  arch-nacl/syscalls/gettimeofday.c \
  arch-nacl/syscalls/getuid.c \
  arch-nacl/syscalls/__ioctl.c \
  arch-nacl/syscalls/kill.c \
  arch-nacl/syscalls/listen.c \
  arch-nacl/syscalls/lseek.c \
  arch-nacl/syscalls/lseek64.c \
  arch-nacl/syscalls/lstat.c \
  arch-nacl/syscalls/mkdir.c \
  arch-nacl/syscalls/mmap.c \
  arch-nacl/syscalls/mprotect.c \
  arch-nacl/syscalls/munmap.c \
  arch-nacl/syscalls/nacl_dyncode_create.c \
  arch-nacl/syscalls/nacl_dyncode_delete.c \
  arch-nacl/syscalls/nacl_errno.c \
  arch-nacl/syscalls/nacl_list_mappings.c \
  arch-nacl/syscalls/nacl_socket.c \
  arch-nacl/syscalls/nacl_stat.c \
  arch-nacl/syscalls/nacl_timespec.c \
  arch-nacl/syscalls/nacl_timeval.c \
  arch-nacl/syscalls/nanosleep.c \
  arch-nacl/syscalls/__open.c \
  arch-nacl/syscalls/poll.c \
  arch-nacl/syscalls/pipe.c \
  arch-nacl/syscalls/read.c \
  arch-nacl/syscalls/recvfrom.c \
  arch-nacl/syscalls/readlink.c \
  arch-nacl/syscalls/recvmsg.c \
  arch-nacl/syscalls/rename.c \
  arch-nacl/syscalls/rmdir.c \
  arch-nacl/syscalls/select.c \
  arch-nacl/syscalls/sendmsg.c \
  arch-nacl/syscalls/sendto.c \
  arch-nacl/syscalls/setsockopt.c \
  arch-nacl/syscalls/shutdown.c \
  arch-nacl/syscalls/sigaction.c \
  arch-nacl/syscalls/socket.c \
  arch-nacl/syscalls/socketpair.c \
  arch-nacl/syscalls/stat.c \
  arch-nacl/syscalls/symlink.c \
  arch-nacl/syscalls/times.c \
  arch-nacl/syscalls/truncate.c \
  arch-nacl/syscalls/unlink.c \
  arch-nacl/syscalls/utimes.c \
  arch-nacl/syscalls/write.c \
  arch-nacl/syscalls/writev.c \
  arch-nacl/tmp/libc_common_stubs.c \
  arch-nacl/tmp/raw_print.c \
  arch-nacl/tmp/libc_stubs.c \
  bionic/glibc_compat.c \
  nacl_stubs.c

C_REGEX_SOURCES = \
  upstream-netbsd/libc/regex/regcomp.c \
  upstream-netbsd/libc/regex/regerror.c \
  upstream-netbsd/libc/regex/regexec.c \
  upstream-netbsd/libc/regex/regfree.c \
  upstream-netbsd/libc/stdlib/lsearch.c \
  upstream-netbsd/libc/string/strxfrm.c

C_STATIC_SOURCES = \
  bionic/libc_init_static.c \

C_DYNAMIC_SOURCES = \
  bionic/libc_init_dynamic.c \


ifeq ($(NACL_ARCH),arm)
ARCH_SOURCES:=arch-arm/bionic/eabi.c arch-arm/bionic/setjmp.S
C_STATIC_SOURCES+=arch-arm/bionic/exidx_static.c
C_DYNAMIC_SOURCES+=arch-arm/bionic/exidx_dynamic.c
endif

ifeq ($(GCC_ARCH),i686)
ARCH_SOURCES:=arch-x86/bionic/setjmp.S
endif

ifeq ($(GCC_ARCH),x86_64)
ARCH_SOURCES:=arch-amd64/bionic/setjmp.S
endif


IRT_SYSCALLS_H := $(INS_ROOT)/../include/irt_syscalls.h
IRT_SYSCALLS_O := ../irt/irt_syscalls.o


COMMON_SOURCES:=$(C_UNISTD_SOURCES) $(C_STDIO_SOURCES) $(C_STDLIB_SOURCES)
COMMON_SOURCES+=$(C_STRING_SOURCES) $(C_MISC_SOURCES) $(C_NACL_SOURCES)
COMMON_SOURCES+=$(ARCH_SOURCES)

LIBC_STATIC_SOURCES:=$(C_STATIC_SOURCES) $(COMMON_SOURCES) $(IRT_SYSCALLS_O)
LIBC_DYNAMIC_SOURCES:=$(C_DYNAMIC_SOURCES) $(COMMON_SOURCES) $(IRT_SYSCALLS_O)

STATIC_OBJECTS = $(subst .S,.o,$(subst .c,.o,$(LIBC_STATIC_SOURCES) $(C_REGEX_SOURCES)))
DYNAMIC_OBJECTS = $(subst .S,.o,$(subst .c,.o,$(LIBC_DYNAMIC_SOURCES) $(C_REGEX_SOURCES)))

LIBC_CC_SOURCES = $(COMMON_SOURCES) $(C_STATIC_SOURCES) $(C_DYNAMIC_SOURCES)

REGEX_FLAGS:=-I$(SRC_ROOT)/upstream-netbsd/libc/regex
REGEX_FLAGS+=-include netbsd-compat.h

DYNAMIC_LINK_FLAGS:=-nostdlib -shared -Wl,-z,defs -L$(INS_ROOT) -L$(GCC_ROOT)


all: compile lib


$(foreach src,$(C_REGEX_SOURCES),$(eval $(call BASIC_COMPILE_TARGET,$(basename $(src)).o,$(SRC_ROOT)/$(src),$(CC),-std=gnu99 -g $(CFLAGS) $(LIBC_CFLAGS) $(ARCH_FLAGS) $(REGEX_FLAGS),,,$(IRT_SYSCALLS_H))))
$(foreach src,$(LIBC_CC_SOURCES),$(eval $(call BASIC_COMPILE_TARGET,$(basename $(src)).o,$(SRC_ROOT)/$(src),$(CC),-std=gnu99 -g $(CFLAGS) $(LIBC_CFLAGS) $(ARCH_FLAGS),,,$(IRT_SYSCALLS_H))))

	
# Fake libdl.so to provide a way to share the IRT pointers
DL_SOURCE:=arch-nacl/bionic/irt_ptrs.c
DL_OBJECT:=$(subst .c,.o,$(DL_SOURCE))

$(eval $(call BASIC_COMPILE_TARGET,$(DL_OBJECT),$(SRC_ROOT)/$(DL_SOURCE),$(CC),-std=gnu99 -g $(CFLAGS) $(LIBC_CFLAGS) $(ARCH_FLAGS),,,$(IRT_SYSCALLS_H)))
$(eval $(call BASIC_LINK_TARGET,$(INS_ROOT)/libdl.so,$(DL_OBJECT),$(LD),-nostdlib -shared))

$(eval $(call BASIC_LIB_TARGET,$(INS_ROOT)/libc.a,$(STATIC_OBJECTS),$(AR)))
$(eval $(call BASIC_LINK_TARGET,$(INS_ROOT)/libc.so,$(INS_ROOT)/crtbeginS.o $(DYNAMIC_OBJECTS) $(INS_ROOT)/crtendS.o ,$(LD),$(DYNAMIC_LINK_FLAGS),-ldl -lgcc,,$(INS_ROOT)/libdl.so))

crt: $(INS_ROOT)/crtbegin.o $(INS_ROOT)/crtbeginS.o $(INS_ROOT)/crtbeginT.o $(INS_ROOT)/crtend.o $(INS_ROOT)/crtendS.o
static: $(INS_ROOT)/libc.a
dynamic: $(INS_ROOT)/libc.so

clean:
	rm -f *.o */*.o */*/*.o */*/*/*.o 
	rm -f *.d */*.d */*/*.d */*/*/*.d
	rm -f $(INS_ROOT)/libc.*
	rm -f $(INS_ROOT)/crtbegin.o $(INS_ROOT)/crtbeginS.o
	rm -f $(INS_ROOT)/crtend.o $(INS_ROOT)/crtendS.o

	